﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using WpfLibrary.Animate;

namespace SY_Library
{
    public static class Animate
    {
        public enum direction
        {
            Width, Height
        }

        public static void Double(FrameworkElement sp, DependencyProperty dp, double Old, double New, double Milliseconds, Action<DoubleAnimation>? action = null)
        {
            DoubleAnimation doubleAnimation = new();
            doubleAnimation.From = Old;
            doubleAnimation.To = New;
            doubleAnimation.Duration = TimeSpan.FromMilliseconds(Milliseconds);
            if (action is not null)
                action(doubleAnimation);
            sp.BeginAnimation(dp, doubleAnimation);
        }
        public static void Move(FrameworkElement sp, Thickness Old, Thickness New, double Milliseconds, Action<ThicknessAnimation>? action = null)
        {
            Storyboard sb = new Storyboard();
            Move(sb, sp, Old, New, Milliseconds, action);
        }
        public static void Move(Storyboard sb, FrameworkElement sp, Thickness Old, Thickness New, double Milliseconds, Action<ThicknessAnimation>? action = null)
        {
            if (Milliseconds < 0)
                return;
            ThicknessAnimation ta = new ThicknessAnimation();
            ta.From = Old;
            ta.To = New;
            ta.Duration = TimeSpan.FromMilliseconds(Milliseconds);
            if (action is not null)
                action(ta);
            sb.Children.Add(ta);
            Storyboard.SetTarget(ta, sp);
            Storyboard.SetTargetProperty(ta, new PropertyPath("Margin"));
            sb.Begin(sp, true);
        }

        public static void Deformation(FrameworkElement sp, direction WH, double Old, double New, double Milliseconds, Action<DoubleAnimation>? action = null)
        {
            Storyboard sb = new Storyboard();
            Deformation(sb, sp, WH, Old, New, Milliseconds, action);
        }
        public static void Deformation(Storyboard sb, FrameworkElement sp, direction WH, double Old, double New, double Milliseconds, Action<DoubleAnimation>? action = null)
        {
            DoubleAnimation ta = new DoubleAnimation();
            ta.From = Old;
            ta.To = New;
            ta.Duration = TimeSpan.FromMilliseconds(Milliseconds);
            if (action is not null)
                action(ta);
            sb.Children.Add(ta);
            Storyboard.SetTarget(ta, sp);
            Storyboard.SetTargetProperty(ta, new PropertyPath(WH.ToString()));
            sb.Begin(sp, true);
        }

        public static void Variation(Grid grid, int index, direction WH, GridLength Old, GridLength New, double Milliseconds, Action<GridLengthAnimation>? action = null)
        {
            GridLengthAnimation ta = new GridLengthAnimation();
            ta.From = Old;
            ta.To = New;
            ta.Duration = TimeSpan.FromMilliseconds(Milliseconds);
            if (action is not null)
                action(ta);
            if (WH == direction.Height)
                grid.RowDefinitions[index].BeginAnimation(RowDefinition.HeightProperty, ta);
            else if (WH == direction.Width)
                grid.ColumnDefinitions[index].BeginAnimation(ColumnDefinition.WidthProperty, ta);
        }

        /// <summary>
        /// 暂停动画[保持原位置]
        /// </summary>
        public static void OutAnimate(Storyboard sb, StackPanel sp, Attribute attribute)
        {
            switch (attribute)
            {
                case Attribute.Margin:
                    var oldMargin = sp.Margin;
                    sb.Remove(sp);
                    sp.Margin = new Thickness(oldMargin.Left, oldMargin.Top, oldMargin.Right, oldMargin.Bottom);
                    break;
                case Attribute.Width:
                    var width = sp.Width;
                    sb.Remove(sp);
                    sp.Width = width;
                    break;
                case Attribute.Height:
                    var height = sp.Height;
                    sb.Remove(sp);
                    sp.Width = height;
                    break;
            }
        }
        /// <summary>
        /// 暂停动画[保持原位置]
        /// </summary>
        public static void OutAnimate(this Storyboard sb, FrameworkElement sp, Attribute attribute)
        {
            OutAnimate(sb, sp, attribute);
        }

        public enum Attribute
        {
            Margin,
            Width,
            Height,
        }
    }
}
